import conversion_send_icon from '@/assets/image/conversion_send.png';
import {
  feedbacksComment,
  helpChat,
  search_feedback,
} from '@/services/ant-design-pro/conversation';
import { AILogsCon } from '@/services/models/dataDoc';
import { isNotEmpty } from '@/utils';
import { CloseCircleOutlined } from '@ant-design/icons/lib/icons';
import { Button, Divider, Form, Input, message, Select } from 'antd';
import { nanoid } from 'nanoid';
import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { connect } from 'umi';
import AgoCommandLogs from './agoCommandLogs';
import AiCommandLogs from './aiCommandLogs';
import './index.less';
const Command: React.FC<any> = forwardRef((props: any, ref) => {
  const { loading, structWrite, generate, visible, stopStruct, showProgress, pollingReqState } =
    props;
  const [ipt, setIpt] = useState<string>('');
  const [aiLogs, setAILogs] = useState<AILogsCon[]>([]); //对话框对话列表
  const [orderSelect, setOrderSelect] = useState('1'); //指令 or 聊天
  const [form] = Form.useForm();
  const [agoLogs, setAgoLogs] = useState([]); //上个页面保存在后台的 引导语、查看示例、示例、用户输入指令
  const [iptPlaceholder, setIptPlaceholder] =
    useState<string>('请输入指令，指令会对整篇文章做修改'); //输入框的placeholder文案
  const messagesEnd = useRef<HTMLDivElement>(null);
  //存储在页面model的数据
  const { curOperationType, currentDocIndex, robotLoading, documentUUID } = props.conversation;

  //公共更新model的方法
  const updateState = (updateObj: any) => {
    props.dispatch({
      type: 'conversation/updateState',
      payload: updateObj,
    });
  };

  //滑动到底部
  const scrollToBottom = (targetClassName = '', speed = 30) => {
    if (messagesEnd && messagesEnd.current) {
      const element = messagesEnd.current;
      let targetPosition = element.scrollHeight;

      if (targetClassName) {
        const targetElement: any = element.querySelector(targetClassName);

        if (targetElement) {
          targetPosition = targetElement?.offsetTop - targetElement?.offsetHeight; // 考虑到滚动到元素顶部
        } else {
          console.error(`找不到 '${targetClassName}'`);
          return; // 如果找不到元素，直接返回，不执行滚动操作
        }
      }

      const startPosition = element.scrollTop;
      const duration = (Math.abs(targetPosition - startPosition) / speed) * 10;
      const startTime = performance.now();

      const animation = (currentTime: any) => {
        const elapsedTime = currentTime - startTime;
        const currentPosition =
          startPosition + ((targetPosition - startPosition) / duration) * elapsedTime;
        element.scrollTop = currentPosition;

        if (elapsedTime < duration) {
          requestAnimationFrame(animation);
        }
      };

      requestAnimationFrame(animation);
    }
  };
  //生成文章 - 发送
  const generateArticle = (keyword: any) => {
    //判断是否有输入
    if (!isNotEmpty(keyword)) {
      message.open({
        type: 'info',
        content: '请输入指令，指令会对整篇文章做修改',
      });
      return;
    }

    form.resetFields();
    setIpt(''); //重置表单的时候 页面上的值清空后 实际上还是有值的 需要手动清空
    const item_user: AILogsCon = {
      key: +new Date() + Math.random(),
      type: 'user',
      user_command: keyword,
    };
    const aiLogsCopy = [...aiLogs];
    aiLogsCopy.push(item_user);
    setAILogs(aiLogsCopy);

    generate(keyword); //调用父页面的发送接口
  };
  const submitZanCai = async () => {
    updateState({
      robotLoading: true,
    });
    //用户输入 如果没有输入 点赞使用 这个内容写得很好，值得表扬 点踩使用 这个内容有待提高，需要改进
    let zanTxt = '这个内容写得很好，值得表扬';
    let caiTxt = '这个内容有待提高，需要改进';
    const { start, end, text, type, position, version_no } = curOperationType.data;
    let reason = ipt ? ipt : type === 1 ? zanTxt : caiTxt;
    let body = {
      document_uuid: documentUUID,
      target_content: text,
      feedback_type: type,
      reason,
      start: start,
      end: end,
      position,
      version_no,
    };
    form.resetFields();
    setIpt(''); //重置表单的时候 页面上的值清空后 实际上还是有值的 需要手动清空
    const res = await feedbacksComment(body);
    if (res.code === 0) {
      let zancaiTip = {
        key: nanoid(),
        type: 'userZanCai',
        data: {
          type,
          reason,
          target_content: text,
          range: curOperationType.data,
        },
      };
      setTimeout(() => {
        setAILogs((prev) => [...prev, zancaiTip]);
        updateState({
          robotLoading: false,
        });
        //发送完毕 更新zan和踩的样式
        updateState({
          curOperationType: {
            type: 'updateZanCai',
            data: curOperationType.data,
          },
        });
      }, 500);
    } else {
      updateState({
        robotLoading: false,
      });
      message.open({
        type: 'error',
        content: res.msg,
      });
    }
  };
  //提交 - 聊天
  const submitChat = async (keyword: any) => {
    //判断是否有输入
    if (!isNotEmpty(keyword)) {
      message.open({
        type: 'info',
        content: '小麦随时为您提供帮助，如提供思路、查询资料等',
      });
      return;
    }
    let userInput = {
      key: nanoid(),
      type: 'userRecover',
      data: keyword,
    };
    setAILogs((prev) => [...prev, userInput]);
    updateState({
      robotLoading: true,
    });
    form.resetFields();
    setIpt(''); //重置表单的时候 页面上的值清空后 实际上还是有值的 需要手动清空
    let body = {
      query: keyword,
    };
    const res = await helpChat(body);
    if (res.code === 0) {
      //假如有小模型回答 先展示小模型 然后再展示问答和文章来源
      const articlesWithKeyword = res.data.articles.map((article: any) => ({
        ...article,
        query: keyword, //query 用于查询相关搜索的值
        keyword: keyword, //获取小模型时的原始输入值 相关搜索时传ids 需要用keyword来匹配确定是否是同一组的id
      }));
      if (res?.data?.articles.length > 0) {
        let systemTxtRecover = {
          key: nanoid(),
          type: 'miniModelArticle',
          isTypewriter: true,
          data: articlesWithKeyword,
        };
        setAILogs((prev) => [...prev, systemTxtRecover]);
        //小于5条表示后面没有数据了
        if (res.data.articles.length <= 4) {
          setTimeout(() => {
            let systemTxtRecover = {
              key: nanoid(),
              type: 'systemTxtRecover',
              spend: 30,
              data: ['非常抱歉，没有更多结果可供显示，请尝试使用其他关键词。'],
            };
            setAILogs((prev: any) => [...prev, systemTxtRecover]);
          }, 800 + 800 * res?.data?.articles.length);
        } else {
          setTimeout(() => {
            let lookRecommend = {
              key: nanoid(),
              type: 'lookRecommend',
              data: {
                ...articlesWithKeyword[0],
                keyword,
                query: keyword,
              },
            };
            setAILogs((prev) => [...prev, lookRecommend]);
          }, 800 + 800 * res?.data?.articles.length);
        }
        setTimeout(() => {
          if (res?.data?.content.length > 0) {
            //添加通用的系统文字回复类型
            let systemTxtRecover = {
              key: nanoid(),
              type: 'systemTxtRecover',
              isTypewriter: true,
              data: res?.data?.content,
              onComplete: () => {
                if (res?.data?.cognitions.length > 0) {
                  // 对应是文章来源的操作
                  let lookSource = {
                    key: nanoid(),
                    type: 'lookSource',
                    data: res?.data?.cognitions,
                  };
                  setAILogs((prev) => [...prev, lookSource]);
                }
              },
            };
            setAILogs((prev) => [...prev, systemTxtRecover]);
          } else {
            if (res?.data?.cognitions.length > 0) {
              // 对应是文章来源的操作
              let lookSource = {
                key: nanoid(),
                type: 'lookSource',
                data: res?.data?.cognitions,
              };
              setAILogs((prev) => [...prev, lookSource]);
            }
          }
        }, 1600 + 800 * res?.data?.articles.length);
      } else if (res?.data?.articles.length === 0) {
        if (res?.data?.content.length > 0) {
          //添加通用的系统文字回复类型
          let systemTxtRecover = {
            key: nanoid(),
            type: 'systemTxtRecover',
            isTypewriter: true,
            data: res?.data?.content,
            onComplete: () => {
              if (res?.data?.cognitions.length > 0) {
                // 对应是文章来源的操作
                let lookSource = {
                  key: nanoid(),
                  type: 'lookSource',
                  data: res?.data?.cognitions,
                };
                setAILogs((prev) => [...prev, lookSource]);
              }
            },
          };
          setAILogs((prev) => [...prev, systemTxtRecover]);
        } else {
          if (res?.data?.cognitions.length > 0) {
            // 对应是文章来源的操作
            let lookSource = {
              key: nanoid(),
              type: 'lookSource',
              data: res?.data?.cognitions,
            };
            setAILogs((prev) => [...prev, lookSource]);
          }
        }
      }

      updateState({
        robotLoading: false,
      });
      // setTimeout(() => {
      //   scrollToBottom()
      // }, 1000);
    } else {
      updateState({
        robotLoading: false,
      });
      message.open({
        type: 'error',
        content: res.msg,
      });
    }
  };

  //踩的反馈提交
  const submitFeedbackCai = async (item: any, item2: any) => {
    let body = {
      query_string: item?.data?.query_string,
      query_result: item?.data?.query_result,
      source: '小模型',
      type: item?.data?.type,
      reason_ids: [],
      other_reason: item2,
    };

    let res = await search_feedback(body);
    if (res.code === 0) {
      let caiTxt = '收到您的反馈，我会总结经验，努力改进的。';
      let zancaiTip = {
        key: nanoid(),
        type: 'userZanCai',
        data: {
          type: item?.data?.type,
          reason: item2,
          target_content: item?.data?.sentence,
          range: null,
        },
      };
      //显示点踩后的交互
      setTimeout(() => {
        setAILogs((prev: any) => [...prev, zancaiTip]);
        updateState({
          robotLoading: false,
          curOperationType: {
            type: 'cancelZanCai',
            data: null,
          },
        });

        form.resetFields();
        setIpt('');
        setOrderSelect('2');
        // eslint-disable-next-line @typescript-eslint/no-use-before-define
        changeOrder('2'); //回到聊天
        let systemTxtRecover = {
          key: nanoid(),
          type: 'systemTxtRecover',
          spend: 30,
          data: [caiTxt],
        };
        setAILogs((prev: any) => [...prev, systemTxtRecover]);
      }, 500);
    } else {
      message.error(res.msg);
    }
  };
  //点击发送按钮
  const handleSubmit = async (keyword: any) => {
    //聊天
    if (orderSelect === '2') {
      await submitChat(keyword);
      return;
    } else if (curOperationType.type === 'zan' || curOperationType.type === 'cai') {
      //点赞和点踩
      submitZanCai();
    } else if (curOperationType.type === 'caiFeedback') {
      //小模型 点踩的反馈
      submitFeedbackCai(curOperationType, keyword);
    } else {
      //用户输入指令的处理
      generateArticle(keyword);
      return;
    }
  };

  //回车触发提交
  const handleKeyDown = (e: any) => {
    if (e.keyCode === 13) {
      handleSubmit(ipt);
    }
  };

  //停止轮询
  const stopSubmit = () => {
    stopStruct();
  };

  //对话框内容变动时 自动滑动到底部
  useEffect(() => {
    scrollToBottom();
  }, [aiLogs]);
  //当前选中文章变动时清空输入框
  useEffect(() => {
    form.resetFields();
    setIpt('');
  }, [currentDocIndex]);

  //监听机器人loading
  useEffect(() => {
    //添加机器人等待
    if (robotLoading && agoLogs.length > 0 && !aiLogs.some((log) => log.type === 'robotLoading')) {
      const robotLoad = {
        key: nanoid(),
        type: 'robotLoading',
      };
      setAILogs((prev) => [...prev, robotLoad]);
    }
    //删除
    if (!robotLoading && agoLogs.length > 0 && aiLogs.some((log) => log.type === 'robotLoading')) {
      setAILogs((prev) => prev.filter((log) => log.type !== 'robotLoading'));
    }
  }, [robotLoading, aiLogs]);

  //监听左侧文章组件点赞 点踩 评分的操作
  useEffect(() => {
    //操作类型 评分score 点赞zan 踩cai cancelZanCai取消赞和踩 输入文字input
    if (curOperationType) {
      let orderType1 = ['zan', 'cai', 'input', 'fanxie', 'gaixie']; //赞和踩 input都属于指令
      //切换到对应的select
      if (orderType1.includes(curOperationType.type)) {
        setOrderSelect('1');
      }
      //评分成功
      if (curOperationType.type === 'score') {
        let userInput = {
          key: nanoid(),
          type: 'userRecover',
          data: '我已给这篇文章评分，继续加油。',
        };
        setAILogs((prev) => [...prev, userInput]);
        setTimeout(() => {
          let scoreTip = {
            key: nanoid(),
            type: 'scoreTip',
            data: '好的，收到您的评价！我会结合您的反馈继续改进，争取做的更好。',
          };
          setAILogs((prev) => [...prev, scoreTip]);
        }, 500);
      }
      if (curOperationType.type === 'zan') {
        setIptPlaceholder('请简要写出点赞原因,  小麦会根据您的描述快速学习，变得更加懂你');
      }
      if (curOperationType.type === 'cai') {
        setIptPlaceholder('请简要写出点踩原因,  小麦会根据您的描述快速学习，变得更加懂你');
      }
      if (curOperationType.type === 'input') {
        setIptPlaceholder('请输入指令，指令会对整篇文章做修改');
      }
      if (curOperationType.type === 'caiFeedback') {
        setIptPlaceholder('请简要写出点踩原因,  小麦会根据您的描述快速学习，变得更加懂你');
        setOrderSelect('1');
      }
    }
  }, [curOperationType]);

  useEffect(() => {
    if (orderSelect) {
    }
  }, [orderSelect]);

  //取消赞和踩
  const cancleZanCai = (data: any) => {
    updateState({
      curOperationType: {
        type: 'cancelZanCai',
        data: data,
      },
    });
  };
  //指令下拉 默认回到文章input模式
  const changeOrder = (val: any) => {
    //1是指令 2是聊天
    setOrderSelect(val);
    if (val === '1') {
      updateState({
        curOperationType: {
          type: 'input',
          data: null,
        },
      });
    } else {
      updateState({
        curOperationType: {
          type: 'chat',
          data: null,
        },
      });
      setIptPlaceholder('小麦随时为您提供帮助，如提供思路、查询资料等');
    }
  };
  //预留触发的方法
  useImperativeHandle(ref, () => ({
    setAILogs,
  }));
  return (
    <div className="aiTalkBox" style={{ display: visible ? 'flex' : 'none' }}>
      <div className="conversationTalkTitle">写作实习生 - 小麦</div>
      <div
        className={`command-con ${
          curOperationType.type === 'zan' || curOperationType.type === 'cai' ? 'haszancai' : ''
        }`}
        ref={messagesEnd}
      >
        <div className="con-box">
          {/* <div className="topMasking"></div> */}
          {/* 初始化从上个页面传来的引导语 查看示例 要点框 篇数  */}
          <AgoCommandLogs
            agoLogs={agoLogs}
            setAgoLogs={setAgoLogs}
            structWrite={structWrite}
            scrollToBottom={scrollToBottom}
            pollingReqState={pollingReqState}
          ></AgoCommandLogs>
          {agoLogs.length > 0 && !showProgress && (
            <Divider className="dividerLine" dashed plain>
              以下指令只针对文章 {currentDocIndex}
            </Divider>
          )}
          <AiCommandLogs
            aiLogs={aiLogs}
            setAILogs={setAILogs}
            scrollToBottom={scrollToBottom}
          ></AiCommandLogs>
        </div>
      </div>
      <div className="command-send-wrap">
        <div className="command-send">
          {!showProgress && (
            <div className="command-type-tag-box">
              <Select
                bordered={false}
                className="selectOrderType"
                size="small"
                value={orderSelect}
                style={{ width: 80 }}
                onChange={changeOrder}
                options={[
                  { value: '1', label: '# 指令' },
                  { value: '2', label: '# 聊天' },
                ]}
              />
              {orderSelect === '1' ? (
                curOperationType.type === 'zan' ? (
                  <div className="command-type-tag cyan">点赞</div>
                ) : curOperationType.type === 'cai' ? (
                  <div className="command-type-tag red">点踩</div>
                ) : curOperationType.type === 'caiFeedback' ? (
                  <div className="command-type-tag red">点踩</div>
                ) : (
                  <div className="command-type-tag">文章{currentDocIndex}</div>
                )
              ) : (
                <></>
              )}
            </div>
          )}

          <Form form={form} name="control-hooks" className="command-form">
            <Form.Item name="content">
              <Input
                value={ipt}
                disabled={loading}
                bordered={false}
                placeholder={iptPlaceholder}
                className="question-input"
                onChange={(e) => setIpt(e.target.value)}
                onKeyDown={handleKeyDown}
                autoComplete="off"
              />
            </Form.Item>
          </Form>
          <Button
            loading={loading}
            disabled={loading}
            type="text"
            onClick={() => handleSubmit(ipt)}
            style={{ background: '#fff', padding: '0 6px' }}
          >
            {!loading && <img src={conversion_send_icon} width={23} height={23} />}
          </Button>
          {showProgress && (
            <div className="stop-btn" onClick={() => stopSubmit()}>
              停止
            </div>
          )}
        </div>
        {curOperationType.type === 'zan' ||
        curOperationType.type === 'cai' ||
        curOperationType.type === 'caiFeedback' ? (
          <div className="zancaiBox">
            <div className="zancai-hd">
              <span>{curOperationType && curOperationType.data?.text}</span>
            </div>
            <span className="zancai-bd" onClick={() => cancleZanCai(curOperationType)}>
              <CloseCircleOutlined />
            </span>
          </div>
        ) : null}
      </div>
    </div>
  );
});

// export default Command;
export default connect(({ conversation }) => ({ conversation }), null, null, { forwardRef: true })(
  Command,
);
